using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;
using PdfLib;
using Workflows.Components.TextMining.Properties;

namespace Workflows.Components.TextMining.PdfBookmarkExtraction
{
    /// <summary>
    /// 
    /// </summary>
    [Serializable]
    public class PdfBookmarkExtractionComponent:WorkflowComponentBase
    {
        #region props
        private PdfBookmarkExtractionInstruction _Instruction;
        private PdfBookmarkExtractionOutput _Output;

        public override InstructionBase Instruction
        {
            get { return _Instruction; }
            set { _Instruction = (PdfBookmarkExtractionInstruction) value; }
        }

        public override ResultBase Output
        {
            get { return _Output; }
            set { _Output = (PdfBookmarkExtractionOutput) value; }
        }
        #endregion

        #region src
        /// <summary></summary>
        public string SrcConnStr
        {
            get
            {
                return this._Instruction.SrcConnStr;
            }
            set
            {
                this._Instruction.SrcConnStr = value;
            }
        }

        /// <summary></summary>
        public string SelectSql
        {
            get
            {
                return this._Instruction.SelectSql;
            }
            set
            {
                this._Instruction.SelectSql = value;
            }
        }

        /// <summary></summary>
        public string FilePathField
        {
            get
            {
                return this._Instruction.FilePathField;
            }
            set
            {
                this._Instruction.FilePathField = value;
            }
        }

        /// <summary></summary>
        public string SrcIDField
        {
            get
            {
                return this._Instruction.SrcIDField;
            }
            set
            {
                this._Instruction.SrcIDField = value;
            }
        }
        #endregion

        #region bookmark
        /// <summary></summary>
        public string BookmarkTitle
        {
            get
            {
                return this._Instruction.BookmarkTitle;
            }
            set
            {
                this._Instruction.BookmarkTitle = value;
            }
        }

        /// <summary></summary>
        public string BookmarkPath
        {
            get
            {
                return this._Instruction.BookmarkPath;
            }
            set
            {
                this._Instruction.BookmarkPath = value;
            }
        }

        /// <summary></summary>
        public string[] BookmarkSearchPatterns
        {
            get
            {
                return this._Instruction.BookmarkSearchPatterns;
            }
            set
            {
                this._Instruction.BookmarkSearchPatterns = value;
            }
        }

        /// <summary></summary>
        public bool AcrossMultipleBookmarks
        {
            get
            {
                return this._Instruction.AcrossMultipleBookmarks;
            }
            set
            {
                this._Instruction.AcrossMultipleBookmarks = value;
            }
        }

        /// <summary></summary>
        public string ToBookmarkTitle
        {
            get
            {
                return this._Instruction.ToBookmarkTitle;
            }
            set
            {
                this._Instruction.ToBookmarkTitle = value;
            }
        }

        /// <summary></summary>
        public string ToBookmarkPath
        {
            get
            {
                return this._Instruction.ToBookmarkPath;
            }
            set
            {
                this._Instruction.ToBookmarkPath = value;
            }
        }

        /// <summary></summary>
        public string[] ToBookmarkPatterns
        {
            get
            {
                return this._Instruction.ToBookmarkPatterns;
            }
            set
            {
                this._Instruction.ToBookmarkPatterns = value;
            }
        }
        #endregion

        #region filter
        /// <summary></summary>
        public List<PdfContentFilter> ContentFilters
        {
            get
            {
                return this._Instruction.ContentFilters;
            }
            set
            {
                this._Instruction.ContentFilters = value;
            }
        }

        /// <summary></summary>
        public bool UseBoxedContent
        {
            get
            {
                return this._Instruction.UseBoxedContent;
            }
            set
            {
                this._Instruction.UseBoxedContent = value;
            }
        }

        /// <summary></summary>
        public float MinWidth
        {
            get
            {
                return this._Instruction.MinWidth;
            }
            set
            {
                this._Instruction.MinWidth = value;
            }
        }

        /// <summary></summary>
        public float MinHeight
        {
            get
            {
                return this._Instruction.MinHeight;
            }
            set
            {
                this._Instruction.MinHeight = value;
            }
        }
        #endregion

        #region tgt
        /// <summary></summary>
        public string TgtConnStr
        {
            get
            {
                return this._Instruction.TgtConnStr;
            }
            set
            {
                this._Instruction.TgtConnStr = value;
            }
        }

        /// <summary></summary>
        public string TargetTableName
        {
            get
            {
                return this._Instruction.TargetTableName;
            }
            set
            {
                this._Instruction.TargetTableName = value;
            }
        }

        /// <summary></summary>
        public string TgtIDField
        {
            get
            {
                return this._Instruction.TgtIDField;
            }
            set
            {
                this._Instruction.TgtIDField = value;
            }
        }

        /// <summary></summary>
        public string BookmarkContentFieldName
        {
            get
            {
                return this._Instruction.BookmarkContentFieldName;
            }
            set
            {
                this._Instruction.BookmarkContentFieldName = value;
            }
        }

        /// <summary></summary>
        public string ExtractFromPageField
        {
            get
            {
                return this._Instruction.ExtractFromPageField;
            }
            set
            {
                this._Instruction.ExtractFromPageField = value;
            }
        }

        /// <summary></summary>
        public string ExtractFromPosField
        {
            get
            {
                return this._Instruction.ExtractFromPosField;
            }
            set
            {
                this._Instruction.ExtractFromPosField = value;
            }
        }

        /// <summary></summary>
        public string ExtractToPageField
        {
            get
            {
                return this._Instruction.ExtractToPageField;
            }
            set
            {
                this._Instruction.ExtractToPageField = value;
            }
        }

        /// <summary></summary>
        public string ExtractToPosField
        {
            get
            {
                return this._Instruction.ExtractToPosField;
            }
            set
            {
                this._Instruction.ExtractToPosField = value;
            }
        }

        /// <summary></summary>
        public string FlagField
        {
            get
            {
                return this._Instruction.FlagField;
            }
            set
            {
                this._Instruction.FlagField = value;
            }
        }

        /// <summary></summary>
        public string UpdField
        {
            get
            {
                return this._Instruction.UpdField;
            }
            set
            {
                this._Instruction.UpdField = value;
            }
        }
        #endregion
        

        /// <summary>
        /// 
        /// </summary>
        public PdfBookmarkExtractionComponent():base()
        {
            this.ComponentActivityType = WorkflowActivityType.SimpleActivity;
            this.ComponentCategory = WorkflowComponentCategory.TextMining.ToString();
            this.ComponentIcon = Resources.adobe;
            this.ComponentImage = Resources.UserMonitor;
            this.ComponentName = "Bookmark extractor";
            this.Description = "Extract pdf content as text based on bookmarks";

            this._Instruction =
                new PdfBookmarkExtractionInstruction(
                    this.ComponentID, Guid.Empty,
                    string.Empty, string.Empty, string.Empty, string.Empty,
                    string.Empty, string.Empty, null, false, string.Empty, string.Empty, null,
                    new List<PdfContentFilter>(), false, 0, 0,
                    string.Empty, string.Empty, string.Empty, string.Empty,
                    string.Empty, string.Empty, string.Empty, string.Empty, 
                    string.Empty, string.Empty);
            this._Output = new PdfBookmarkExtractionOutput(this.ComponentID, Guid.Empty, 0, 0);
        }

        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = base.Serialize(ref xDoc, ref parentNode);

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SrcConnStr", this.SrcConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SelectSql", this.SelectSql);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FilePathField", this.FilePathField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SrcIDField", this.SrcIDField);

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BookmarkTitle", this.BookmarkTitle);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BookmarkPath", this.BookmarkPath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BookmarkSearchPatterns",
                                        StringUtil.ToString(this.BookmarkSearchPatterns));
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "AcrossMultipleBookmarks", this.AcrossMultipleBookmarks.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToBookmarkTitle", this.ToBookmarkTitle);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToBookmarkPath", this.ToBookmarkPath);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToBookmarkPatterns",
                                        StringUtil.ToString(this.ToBookmarkPatterns));

            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtConnStr", this.TgtConnStr);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtTable", this.TargetTableName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TgtIDField", this.TgtIDField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "BookmarkContentField", this.BookmarkContentFieldName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FromPageField", this.ExtractFromPageField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FromPosField", this.ExtractFromPosField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToPageField", this.ExtractToPageField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToPosField", this.ExtractToPosField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "FlagField", this.FlagField);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "UpdField",this.UpdField);

            if (this.ContentFilters != null && this.ContentFilters.Count > 0)
            {
                XmlNode filterRootNode = XmlDataUtil.AddElement(ref xDoc, xNode, "ContentFilters");
                foreach (PdfContentFilter filter in this.ContentFilters)
                {
                    XmlNode filterNode = XmlDataUtil.AddElement(ref xDoc, filterRootNode, "ContentFilter");
                    XmlDataUtil.UpdateAttribute(ref xDoc, filterNode, "HeaderPattern", filter.HeaderPattern);
                    XmlDataUtil.UpdateAttribute(ref xDoc, filterNode, "FooterPattern", filter.FooterPattern);
                    XmlDataUtil.UpdateAttribute(ref xDoc, filterNode, "SkipHeader", filter.SkipHeader.ToString());
                    XmlDataUtil.UpdateAttribute(ref xDoc, filterNode, "SkipFooter", filter.SkipFooter.ToString());
                }
            }
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "UseBoxedContent", this.UseBoxedContent.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "MinWidth", this.MinWidth.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "MinHeight", this.MinHeight.ToString());

            return xNode;
        }

        public override WorkflowComponentBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                PdfBookmarkExtractionComponent wfComponent = base.Instantiate(xNode) as PdfBookmarkExtractionComponent;

                wfComponent.SrcConnStr = XmlDataUtil.GetAttributeValue(xNode, "SrcConnStr", "");
                wfComponent.SelectSql = XmlDataUtil.GetAttributeValue(xNode, "SelectSql", "");
                wfComponent.FilePathField = XmlDataUtil.GetAttributeValue(xNode, "FilePathField", "");
                wfComponent.SrcIDField = XmlDataUtil.GetAttributeValue(xNode, "SrcIDField", "");

                wfComponent.BookmarkTitle = XmlDataUtil.GetAttributeValue(xNode, "BookmarkTitle", "");
                wfComponent.BookmarkPath = XmlDataUtil.GetAttributeValue(xNode, "BookmarkPath", "");
                wfComponent.BookmarkSearchPatterns =
                    StringUtil.Split(XmlDataUtil.GetAttributeValue(xNode, "BookmarkSearchPatterns", ""));
                wfComponent.AcrossMultipleBookmarks =
                    bool.Parse(XmlDataUtil.GetAttributeValue(xNode, "AcrossMultipleBookmarks", false.ToString()));
                wfComponent.ToBookmarkTitle = XmlDataUtil.GetAttributeValue(xNode, "ToBookmarkTitle", "");
                wfComponent.ToBookmarkPath = XmlDataUtil.GetAttributeValue(xNode, "ToBookmarkPath", "");
                wfComponent.ToBookmarkPatterns =
                    StringUtil.Split(XmlDataUtil.GetAttributeValue(xNode, "ToBookmarkPatterns", ""));

                XmlNodeList filterNodes = xNode.SelectNodes("ContentFilters/ContentFilter");
                if (filterNodes != null && filterNodes.Count > 0)
                {
                    wfComponent.ContentFilters = new List<PdfContentFilter>();
                    foreach (XmlNode filterNode in filterNodes)
                    {
                        string headerPattern = XmlDataUtil.GetAttributeValue(filterNode, "HeaderPattern", "");
                        bool skipHeader =
                            bool.Parse(XmlDataUtil.GetAttributeValue(filterNode, "SkipHeader", false.ToString()));
                        string footerPattern = XmlDataUtil.GetAttributeValue(filterNode, "FooterPattern", "");
                        bool skipFooter =
                            bool.Parse(XmlDataUtil.GetAttributeValue(filterNode, "SkipFooter", false.ToString()));
                        PdfContentFilter filter = new PdfContentFilter(headerPattern, skipHeader, footerPattern, skipFooter);
                        wfComponent.ContentFilters.Add(filter);
                    }
                }
                wfComponent.UseBoxedContent =
                    bool.Parse(XmlDataUtil.GetAttributeValue(xNode, "UseBoxedContent", false.ToString()));
                wfComponent.MinWidth =
                    float.Parse(XmlDataUtil.GetAttributeValue(xNode, "MinWidth", "0"));
                wfComponent.MinHeight =
                    float.Parse(XmlDataUtil.GetAttributeValue(xNode, "MinHeight", "0"));

                wfComponent.TgtConnStr = XmlDataUtil.GetAttributeValue(xNode, "TgtConnStr", "");
                wfComponent.TargetTableName = XmlDataUtil.GetAttributeValue(xNode, "TgtTable", "");
                wfComponent.TgtIDField = XmlDataUtil.GetAttributeValue(xNode, "TgtIDField", "");
                wfComponent.BookmarkContentFieldName = XmlDataUtil.GetAttributeValue(xNode, "BookmarkContentField", "");
                wfComponent.ExtractFromPageField = XmlDataUtil.GetAttributeValue(xNode, "FromPageField", "");
                wfComponent.ExtractFromPosField = XmlDataUtil.GetAttributeValue(xNode, "FromPosField", "");
                wfComponent.ExtractToPageField = XmlDataUtil.GetAttributeValue(xNode, "ToPageField", "");
                wfComponent.ExtractToPosField = XmlDataUtil.GetAttributeValue(xNode, "ToPosField", "");
                wfComponent.FlagField = XmlDataUtil.GetAttributeValue(xNode, "FlagField", "");
                wfComponent.UpdField = XmlDataUtil.GetAttributeValue(xNode, "UpdField", "");

                return wfComponent;
            }
            else
            {
                throw new Exception("Unable to instantiate component: invalid type specified in xml node");
            }
        }
    }
}
